package com.poizon.infrastructure.idem.core.domain.value.config;

import com.poizon.infrastructure.idem.core.domain.value.enums.IdemDbStoreType;
import com.poizon.infrastructure.idem.core.domain.value.enums.IdemReqType;
import com.poizon.infrastructure.idem.core.domain.value.exception.IdempotentErrorEnum;
import com.poizon.infrastructure.idem.core.domain.value.exception.IdempotentException;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 幂等框架相关常量
 * (可以基于listener动态变更配置)
 */
@Slf4j
public class IdemConstants {
    public static final String DB_STORE_TYPE_CONFIG = "poizon.idem.dbStoreTypeEnum";
    public static final String POIZON_IDEM_REPEATED_SUBMIT_EXPIRE_TIME = "poizon.idem.repeatedSubmit.expireTime";
    public static final String POIZON_IDEM_EXPIRE_TIME = "poizon.idem.expireTime";
    public static final String POIZON_IDEM_PREFIX = "poizon.idem.prefix";
    public static final String POIZON_IDEM_TIME_UNIT = "poizon.idem.timeUnit";
    public static final String POIZON_IDEM_MAX_RETRY_TIMES = "poizon.idem.retryCount";
    public static final String POIZON_IDEM_DB_ERROR_THREASHOLD = "poizon.idem.dbErrorThreashold";
    public static final String POIZON_REPEATED_SUBMIT_TIME_UNIT = "poizon.repeatedSubmit.timeUnit";
    public static final String POIZON_IDEM_RETRY_TIME = "poizon.idem.retryTime";

    /**
     * 幂等 防重提交 键前缀
     */
    public static String IDEM_KEY_PREFIX = "idem:";
    /**
     * 默认幂等建过期时间 1天
     */
    public static Long DEFAULT_IDEM_KEY_EXPIRE_TIME = 1L;


    // -------------------------------------------幂等基础属性------------------------------------------------------
    public static final AtomicInteger dbErrorCounter = new AtomicInteger(0); // DB切换错误计数器

    /**
     * 示例默认重复执行/日志记录
     */
    public static final Runnable DEFAULT_REPEATED_RUNNABLE = () -> {
        log.debug(">默认重复执行逻辑");
        throw new IdempotentException(IdempotentErrorEnum.DUPLICATE_SUBMISSION);
    };
    /**
     * 幂等请求类型
     */
    public static String DEFAULT_IDEM_REQ_TYPE = IdemReqType.HTTP.name();


    // -----------------------------------------幂等基础属性------------------------------------------------------



    /**
     * 默认幂等键过期时间单位
     */
    public static TimeUnit DEFAULT_IDEM_KEY_TIME_UNIT = TimeUnit.DAYS;

    /**
     * 默认幂等最大重试次数
     */
    public static int DEFAULT_MAX_RETRY_TIMES = 3;



    /**
     * 幂等默认重试等待时间(单位ms) 时间太短也会导致异常
     * 注意: 等待时间,必须在rpc时间范围内,不然会直接导致rpc超时
     */
    public static int IDEM_RETRY_WAIT_TIME = 300;

    // DB切换错误阈值
    public static Integer DB_ERROR_THRESHOLD = 3;


    // -----------------------------------------------------默认防重提交配置---------------------------------------------------------
    /**
     * 从配置文件加载 默认幂等的底层实现 不配置默认redis存储
     */
    public static String IDEM_DB_STORE_TYPE = IdemDbStoreType.redis.getDbStoreType();

    /**
     * 默认防重提交建过期时间单位
     */
    public static TimeUnit DEFAULT_REPEATED_SUBMIT_KEY_TIME_UNIT = TimeUnit.DAYS;

    /**
     * 空运行逻辑作为默认服务任务
     */
    public static final Runnable DEFAULT_SERVICE_RUNNABLE = () -> {
    };

    /**
     * 默认防重提交过期时间
     */
    public static Long DEFAULT_REPEATED_SUBMIT_KEY_EXPIRE_TIME = 10L;
    // -----------------------------------------------------默认防重提交配置---------------------------------------------------------
}
